//
// Created by feng on 19-4-15.
//

#ifndef SOLARENERGY_CHIER_QUASIMONTECARLORAYTRACER_H
#define SOLARENERGY_CHIER_QUASIMONTECARLORAYTRACER_H

#include "RayTracingArgumentStruct.h"
#include <algorithm/rayTracing/dataLoader/CloudLoader.h>

#include <memory>

namespace solar
{
    class CloudLoader;
    class SceneField;
    namespace cuda
    {
        struct SunrayArgument;
        class CudaMultiPanelReceiver;
        class CudaRectangleGrid;
        struct HeliostatArgument;
        class CudaSunray;
    } // namespace cuda
} // namespace solar

namespace solar
{
    class QuasiMonteCarloRayTracer
    {
        public:
            // void rayTracing(SolarScene *solarScene, int heliostat_id,bool res);
            // void rayTracing_(SolarScene *solarScene, int heliostat_nums,float3
            // *d_subHeliostat_vertexe,bool res, CloudLoader *cloud);

            void rayTracingViaField(std::shared_ptr<SceneField> field, int heliostat_nums,
                                    float3* d_subHeliostat_vertexe, bool res, CloudLoader* cloud);

            /**
             *  Public following function just for test. Do not use them standalone.
             */
            // void checkValidHeliostatIndex(SolarScene *solarScene, int heliostat_id);

            static constexpr auto receiverGridCombination(int receiver_type, int grid_type) -> int
            {
                return receiver_type * 10 + grid_type;
            }
            

            // HeliostatArgument generateHeliostatArgument(SolarScene *solarScene, int
            // heliostat_id); HeliostatArgument generateHeliostatArguments(SolarScene *solarScene,
            // int heliostat_nums,int map_size);
            [[nodiscard]] auto generateRectHelio(std::shared_ptr<SceneField> field, int micro_nums_per_helio,
                                   int micro_nums_per_sub) const -> cuda::HeliostatArgument;
            static auto generateSunrayArgument(const std::shared_ptr<cuda::CudaSunray>& sunray) -> cuda::SunrayArgument;

            // int setFlatRectangleHeliostatVertexs(float3 *&d_heliostat_vertexs,
            // std::vector<Heliostat
            // *> &heliostats, int start_id, int end_id);

            cudaStream_t stream_;
    };
} // namespace solar

#endif // SOLARENERGY_CHIER_QUASIMONTECARLORAYTRACER_H
